package io.modelcontextprotocol.sdk;

import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.Map;

/**
 * 高级MCP客户端测试 - 演示为什么需要SSE而不是普通HTTP请求
 * <p>
 * 这个测试展示了MCP协议的核心优势： 1. 实时接收进度推送 2. 实时接收日志输出 3. 实时接收资源更新 4. 支持AI交互功能
 * <p>
 * 这些功能用普通HTTP请求-响应模式是无法实现的！
 */
public class AdvancedMcpClientTest {

    private static final Logger logger = LoggerFactory.getLogger(AdvancedMcpClientTest.class);

        // 配置模拟器转发,把模拟器宿主机的ip端口映射的模拟器的8080端口上: adb forward tcp:8080 tcp:8080, 在宿主机上访问: http://localhost:8080 就可以连接到模拟器了
    	private static final String SERVER_URL = "http://localhost:8080";
//    private static final String SERVER_URL = "http://192.168.0.104:8080";

    public static void main(String[] args) {
        logger.info("🚀 高级MCP客户端测试 - 演示SSE vs HTTP请求的差异");
        logger.info("==================================================");
        logger.info(SERVER_URL + "/sse");
        logger.info(SERVER_URL + "/message");

        try {
            // 1. 创建HTTP SSE传输层
            McpClientTransport transport = HttpClientSseClientTransport.builder(SERVER_URL).sseEndpoint("/sse").build();

            logger.info("📡 创建HTTP SSE传输层成功");

            // 2. 创建同步MCP客户端，配置各种消费者
            McpSyncClient client = McpClient.sync(transport)
                    .requestTimeout(Duration.ofSeconds(30))
                    .initializationTimeout(Duration.ofSeconds(5))
                    .capabilities(McpSchema.ClientCapabilities.builder().roots(true).sampling().build())
                    .clientInfo(new McpSchema.Implementation("advanced-mcp-client", "2.0.0"))
                    .loggingConsumer(notification -> {
                        // 实时接收服务器推送的日志
                        logger.info("📝 [实时日志] [{}] {}: {}", notification.level(), notification.logger(),
                                notification.data());
                    })
                    .progressConsumer(notification -> {
                        // 实时接收进度更新
                        logger.info("📊 [进度更新] {}: {}/{} - {}", notification.progressToken(), notification.progress(),
                                notification.total(), notification.message());
                    })
                    .build();

            logger.info("🔧 创建高级MCP客户端成功");

            // 3. 执行各种测试
//            runProgressTest(client);
//            runLoggingTest(client);
//            runAiTest(client);
            runStreamingTest(client);

            logger.info("✅ 所有测试完成 - 这些功能用普通HTTP请求是无法实现的！");

            Thread.sleep(24 * 60 * 60_000);

        } catch (Exception e) {
            logger.error("❌ 测试失败", e);
        }
    }

    /**
     * 测试1: 进度推送功能 演示为什么需要SSE - 普通HTTP请求无法实现实时进度推送
     */
    private static void runProgressTest(McpSyncClient client) {
        logger.info("\n🧪 测试1: 进度推送功能");
        logger.info("----------------------------");
        logger.info("💡 这个功能用普通HTTP请求-响应模式是无法实现的！");
        logger.info("💡 普通HTTP: 请求 → 等待 → 响应 (无法实时推送进度)");
        logger.info("💡 MCP+SSE: 请求 → 实时进度推送 → 最终响应");

        try {
            // 初始化客户端
            client.initialize();
            logger.info("✅ 客户端初始化成功");

            // 调用带进度推送的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_weather_with_progress",
                    Map.of("city", "beijing", "country_code", "CN"));

            logger.info("🌤️ 调用带进度的天气查询...");
            logger.info("📊 注意观察实时进度推送 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 天气查询完成");
            logger.info("📄 最终结果: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 进度测试失败", e);
        }
    }

    /**
     * 测试2: 日志推送功能 演示实时日志输出 - 普通HTTP请求无法实现
     */
    private static void runLoggingTest(McpSyncClient client) {
        logger.info("\n🧪 测试2: 日志推送功能");
        logger.info("----------------------------");
        logger.info("💡 这个功能用普通HTTP请求-响应模式是无法实现的！");
        logger.info("💡 普通HTTP: 无法实时推送日志信息");
        logger.info("💡 MCP+SSE: 可以实时推送详细的处理日志");

        try {
            // 调用带日志输出的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_weather_with_logs",
                    Map.of("city", "shanghai", "detailed", true));

            logger.info("📊 调用带日志的天气查询...");
            logger.info("📝 注意观察实时日志推送 (这些日志通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 天气查询完成");
            logger.info("📄 最终结果: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 日志测试失败", e);
        }
    }

    /**
     * 测试3: AI交互功能 演示AI增强功能 - 普通HTTP请求无法实现复杂的AI交互
     */
    private static void runAiTest(McpSyncClient client) {
        logger.info("\n🧪 测试3: AI交互功能");
        logger.info("----------------------------");
        logger.info("💡 这个功能用普通HTTP请求-响应模式是无法实现的！");
        logger.info("💡 普通HTTP: 无法支持复杂的AI交互流程");
        logger.info("💡 MCP+SSE: 支持AI采样、用户启发等复杂交互");

        try {
            // 调用带AI交互的工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_weather_with_ai",
                    Map.of("city", "guangzhou", "ai_enhanced", true));

            logger.info("🤖 调用带AI的天气查询...");
            logger.info("🧠 注意观察AI处理日志 (这些信息通过SSE实时推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ AI天气分析完成");
            logger.info("📄 AI增强结果: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ AI测试失败", e);
        }
    }

    /**
     * 测试4: 流式数据推送 演示实时数据流 - 普通HTTP请求无法实现持续的数据推送
     */
    private static void runStreamingTest(McpSyncClient client) {
        logger.info("\n🧪 测试4: 流式数据推送");
        logger.info("----------------------------");
        logger.info("💡 这个功能用普通HTTP请求-响应模式是无法实现的！");
        logger.info("💡 普通HTTP: 无法实现持续的数据流推送");
        logger.info("💡 MCP+SSE: 可以持续推送实时数据流");

        try {
            // 调用流式数据工具
            McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("get_weather_streaming",
                    Map.of("city", "shenzhen", "duration", 500000000 // 推送5秒
                    ));

            logger.info("🌊 调用流式天气数据推送...");
            logger.info("📡 注意观察实时数据流 (这些数据通过SSE持续推送):");

            McpSchema.CallToolResult result = client.callTool(request);

            logger.info("✅ 流式数据推送完成");
            logger.info("📄 流式结果: {}", result.content());

        } catch (Exception e) {
            logger.error("❌ 流式测试失败", e);
        }
    }

}
